<template>
    <el-form label-width="100px">
        <el-form-item label="SPU名称">
            <el-input placeholder="请输入SPU名称" v-model="SpuParams.spuName"></el-input>
        </el-form-item>
        <el-form-item label="SPU品牌">
            <el-select v-model="SpuParams.tmId">
                <el-option v-for="(item, index) in AllTradeMark" :key="item.id" :value="item.id"
                    :label="item.tmName"></el-option>
            </el-select>
        </el-form-item>
        <el-form-item label=" SPU描述">
            <el-input type="textarea" style="height:auto" placeholder="请输入描述" v-model="SpuParams.description"></el-input>
        </el-form-item>
        <el-form-item label="SPU图标">
            <!-- upload的v-model 用于展示默认数据 -->
            <el-upload v-model:file-list="imgList" action="/api/admin/product/fileUpload" list-type="picture-card"
                :on-preview="handlePictureCardPreview" :on-remove="handleRemove" :before-upload="beforeAvatarUpload">
                <el-icon>
                    <Plus />
                </el-icon>
            </el-upload>
            <el-dialog v-model="dialogVisible">
                <img w-full :src="dialogImgUrl" alt="预览图" style="width:100%;height:100%">
            </el-dialog>
        </el-form-item>
        <el-form-item label="SPU销售属性" v-model="SpuParams.spuSaleAttrList">
            <!-- 展示销售属性下拉菜单 -->
            <el-select v-model="saleAttrIdAndvalueName"
                :placeholder="unSelectSaleAttr.length ? `还未选择${unSelectSaleAttr.length}个` : '无'">
                <el-option :value="`${item.id}:${item.name}`" :label="item.name" v-for="(item, index) in unSelectSaleAttr  "
                    :key="item.id">{{
                        item.name }}</el-option>
            </el-select>
            <el-button @click="addAttr" type="primary" size="default" icon="Plus" style="margin:0 10px">添加销售属性</el-button>
            <!-- tabel 展示销售属性与属性值的地方 -->
            <el-table border style="margin:10px 0" :data=saleAttr>
                <el-table-column label="序号" width="120px" type="index" align="center"></el-table-column>
                <el-table-column label="销售属性名字" width="150px" prop="saleAttrName"></el-table-column>
                <el-table-column label="销售属性值">
                    <!-- row即是当前SPU已有的销售属性对象 -->
                    <template #="{ row, $index }">
                        <el-tag @close="row.spuSaleAttrValueList.splice(index, 1)"
                            v-for="(item, index) in row.spuSaleAttrValueList" :key="row.id" style="margin:0 5px"
                            class="mx-1" closable>
                            {{ item.saleAttrValueName }}
                        </el-tag>
                        <el-input @blur="toLook(row)" v-model="row.saleAttrValue" v-if="row.flag == true"
                            placeholder="请输入属性值" size="small" style="width:120px"></el-input>
                        <el-button v-else @click="toEdit(row)" icon="Plus" type="primary"></el-button>
                    </template>
                </el-table-column>
                <el-table-column label="操作" width="150px">
                    <template #="{ row, $index }">
                        <el-button icon="Delete" size="small" type="danger" @click="saleAttr.splice($index, 1)"></el-button>
                    </template>
                </el-table-column>
            </el-table>
        </el-form-item>
        <el-form-item>
            <el-button :disabled="saleAttr.length > 0 ? false : true" type="primary" @click="save">保存</el-button>
            <el-button type="primary" @click="cancel">取消</el-button>
        </el-form-item>
    </el-form>
</template>
<script setup lang='ts'>
import { ref, watch, computed } from 'vue'
//引入返回值的接口类型
import type { SpuData, SaleAttrValue, SpuImage, saleAttr, HasSaleAttr, TradeMark, AllTradeMark, HasSaleAttrResponseData, SpuHasImg, SaleAttrResponseData } from '@/api/product/spu/type'
//返回值的接口类型
import { reqAllImage, reqAllTradeMark, reqSpuHasSaleAttr, reqAllSaleAttr, reqAddOrUpdate } from '@/api/product/spu/index'
import { ElMessage } from 'element-plus';
const $emit = defineEmits(['changeSence'])
//点击取消按钮的回调,向父组件传参
const cancel = () => {
    $emit('changeSence', { boo: true, params: 'update' })
}

//存储数据的数组
let AllTradeMark = ref<TradeMark[]>([]);
//存储照片墙数组
let imgList = ref<SpuImage[]>([]);
//存储SPU销售属性的数据的数组
let saleAttr = ref<saleAttr[]>([]);
//存储所有销售属性数据的数组
let allSaleAttr = ref<HasSaleAttr[]>([]);
//存储已有的SPU对象
let SpuParams = ref<SpuData>({
    category3Id: '',//分类Id
    spuName: '',//SPU的名称
    description: '',//简介
    tmId: '',//品牌的ID
    spuImageList: [],
    spuSaleAttrList: []
});
//控制图片显隐
let dialogVisible = ref<boolean>(false)
//存储预览图片的地址
let dialogImgUrl = ref<string>('')
//计算出当前SPU没有的销售属性
let unSelectSaleAttr = computed(() => {
    let unSelectAttr = allSaleAttr.value.filter(item => {
        return saleAttr.value.every((item1) => { return item.name != item1.saleAttrName })
    })
    return unSelectAttr
})

//收集还未选择的销售属性的ID和name
let saleAttrIdAndvalueName = ref<string>('')
//子组件的方法
const initHasSpuData = async (spu: SpuData) => {
    //存储已有的SPU对象
    SpuParams.value = spu;
    // console.log('收集到的Spu', SpuParams.value)
    // spu 父组件的spu对象(不完整)
    //获取全部品牌的数据
    let result: AllTradeMark = await reqAllTradeMark()
    //获取已有的SPU商品的图片
    let result1: SpuHasImg = await reqAllImage(spu.id as number)
    //获取已有的SPU销售属性的数据
    let result2: SaleAttrResponseData = await reqSpuHasSaleAttr(spu.id as number)
    //获取所有销售属性的数据
    let result3: HasSaleAttrResponseData = await reqAllSaleAttr()
    console.log(result, result1, result2, result3)

    //存储全部品牌的数据
    AllTradeMark.value = result.data;
    console.log(AllTradeMark.value)
    // console.log('全部品牌数据', AllTradeMark.value)
    //存储照片墙的数据
    imgList.value = result1.data.map(item => {
        return {
            name: item.imgName,
            url: item.imgUrl,
        }
    });
    // console.log('照片墙数据', imgList.value)
    //存储销售属性的数据
    saleAttr.value = result2.data;
    // console.log('销售属性数据', saleAttr.value)
    //存储所有销售属性的数据
    allSaleAttr.value = result3.data;
    // console.log('所有销售属性数据', allSaleAttr.value)
}

//照片墙预览触发的函数
const handlePictureCardPreview = (file: any) => {
    dialogVisible.value = true;
    dialogImgUrl.value = file.url;
}
//照片墙删除触发的函数
const handleRemove = (file: any) => {
    dialogVisible.value = true;
    dialogImgUrl.value = file.url;
}
//文件上传时进行限制
const beforeAvatarUpload = (rawFile: any) => {

    // 该钩子在上传成功之前触发,用于对文件的类型和大小进行限制
    if (rawFile.type == 'image/jpeg' || rawFile.type == 'image/gif' || rawFile.type == 'image/png') {
        if (rawFile.size / 1024 / 1024 < 4) {
            return true;
        } else {
            ElMessage({
                type: 'error',
                message: '上传的文件大小不超过4M'
            })
            return false;
        }
    } else {
        ElMessage({
            type: 'error',
            message: '上传的文件格式必须为PNG/JPEG/GIF'
        })
        return false;
    }
}
//添加销售属性的方法
const addAttr = () => {
    let [baseSaleAttrId, saleAttrName] = saleAttrIdAndvalueName.value.split(':');
    //准备一个新的销售属性对象,然后带给服务器
    let newSaleAttr: saleAttr = {
        baseSaleAttrId,
        saleAttrName,
        spuSaleAttrValueList: []
    }
    //追加到数组当中
    saleAttr.value.push(newSaleAttr)
}

//属性值按钮的回调
const toEdit = (row: saleAttr) => {
    //点击按钮的时候修改flag,则input显示
    row.flag = true;
    row.saleAttrValue = ''
}
//表单元素失去焦点的回调函数
const toLook = (row: saleAttr) => {
    //整理收集到的属性ID和属性值
    const { baseSaleAttrId, saleAttrValue } = row
    //整理成服务器需要的数据形式
    let newSaleAttrValue: SaleAttrValue = {
        baseSaleAttrId,
        saleAttrValueName: (saleAttrValue as string)
    }
    //非法判断
    if ((saleAttrValue as string).trim() == '') {
        ElMessage({
            type: 'error', message: '属性值不能为空'
        })
        return;
    }
    //判断属性值是否已经存在
    let repeat = row.spuSaleAttrValueList.find(item => {
        return item.saleAttrValueName == saleAttrValue;
    })
    if (repeat) {
        ElMessage({
            type: "error",
            message: "属性值不能重复"
        })
        return;
    }

    row.flag = false;
    //追加新的属性值对象
    row.spuSaleAttrValueList.push(newSaleAttrValue);
}

//保存按钮的回调
const save = async () => {
    //整理参数
    //照片墙
    SpuParams.value.spuImageList = imgList.value.map((item: any) => {
        return {
            imgName: item.name,//图片的名字
            imgUrl: (item.response && item.response.data) || item.url
        }
    })
    //销售属性
    SpuParams.value.spuSaleAttrList = saleAttr.value;
    //发起请求
    let result = await reqAddOrUpdate(SpuParams.value)
    if (result.code == 200) {
        //请求成功
        ElMessage({
            type: 'success',
            message: SpuParams.value.id ? '更新成功' : '添加成功'
        })

        $emit('changeSence', { boo: true, params: SpuParams.value.id ? 'update' : 'add' })
    } else {
        //请求失败
        ElMessage({
            type: 'error',
            message: SpuParams.value.id ? '更新失败' : '添加失败'
        })
    }
}

//添加一个新的spu
const initAddSpu = async (c3Id: number | string) => {
    //清空数据
    Object.assign(SpuParams.value, {
        category3Id: '',//分类Id
        spuName: '',//SPU的名称
        description: '',//简介
        tmId: '',//品牌的ID
        spuImageList: [],
        spuSaleAttrList: []
    });
    imgList.value = [];
    //清空销售属性
    saleAttr.value = []
    //清空收集到的销售属性的标签
    saleAttrIdAndvalueName.value = '';
    //存储分类的Id
    SpuParams.value.category3Id = c3Id
    //获取全部品牌的数据
    let result: AllTradeMark = await reqAllTradeMark()
    //获取所有销售属性的数据
    let result1: HasSaleAttrResponseData = await reqAllSaleAttr()
    //存储全部品牌的数据
    AllTradeMark.value = result.data;
    //存储全部销售属性的数据
    allSaleAttr.value = result1.data;
    console.log(AllTradeMark.value, allSaleAttr.value)
}
defineExpose({ initHasSpuData, initAddSpu })
</script>
<style lang='scss' scoped></style>